home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 008a / perl40_2.zip / DIRECTOR.C < prev    next >
C/C++ Source or Header  |  1991-11-28  |  4KB  |  206 lines

  1. /* $RCSfile: directory.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:24 $
  2.  *
  3.  *    (C) Copyright 1987, 1988, 1990 Diomidis Spinellis.
  4.  *
  5.  *    You may distribute under the terms of either the GNU General Public
  6.  *    License or the Artistic License, as specified in the README file.
  7.  *
  8.  * $Log:    directory.c,v $
  9.  * Revision 4.0.1.1  91/06/07  11:22:24  lwall
  10.  * patch4: new copyright notice
  11.  *
  12.  * Revision 4.0  91/03/20  01:34:24  lwall
  13.  * 4.0 baseline.
  14.  *
  15.  * Revision 3.0.1.1  90/03/27  16:07:37  lwall
  16.  * patch16: MSDOS support
  17.  *
  18.  * Revision 1.3  90/03/16  22:39:40  dds
  19.  * Fixed malloc problem.
  20.  *
  21.  * Revision 1.2  88/07/23  00:08:39  dds
  22.  * Added inode non-zero filling.
  23.  *
  24.  * Revision 1.1  88/07/23  00:03:50  dds
  25.  * Initial revision
  26.  *
  27.  */
  28.  
  29.  
  30. /*
  31.  * UNIX compatible directory access functions
  32.  */
  33.  
  34.  
  35. #include <sys/types.h>
  36. #include <sys/dir.h>
  37. #include <stddef.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <dos.h>
  41. #include <ctype.h>
  42.  
  43.  
  44. /*
  45.  * File names are converted to lowercase if the
  46.  * CONVERT_TO_LOWER_CASE variable is defined.
  47.  */
  48. #define CONVERT_TO_LOWER_CASE
  49.  
  50.  
  51. #define PATHLEN 65
  52.  
  53.  
  54. #ifndef lint
  55. static char rcsid[] = "$RCSfile: directory.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:24 $";
  56. #endif
  57.  
  58.  
  59. DIR *
  60. opendir(char *filename)
  61. {
  62.     DIR            *p;
  63.     char           *oldresult, *result;
  64.     union REGS      srv;
  65.     struct SREGS    segregs;
  66.     register        reslen = 0;
  67.     char            scannamespc[PATHLEN];
  68.     char        *scanname = scannamespc;    /* To take address we need a pointer */
  69.  
  70.  
  71.     /*
  72.      * Structure used by the MS-DOS directory system calls.
  73.      */
  74.     struct dir_buff {
  75.         char            reserved[21];    /* Reserved for MS-DOS */
  76.         unsigned char   attribute;    /* Attribute */
  77.         unsigned int    time;        /* Time */
  78.         unsigned int    date;        /* Date */
  79.         long            size;        /* Size of file */
  80.         char            fn[13];        /* Filename */
  81.     } buffspc, *buff = &buffspc;
  82.  
  83.  
  84.  
  85.  
  86.     if (!(p = (DIR *) malloc(sizeof(DIR))))
  87.         return NULL;
  88.  
  89.  
  90.     /* Initialize result to use realloc on it */
  91.     if (!(result = malloc(1))) {
  92.         free(p);
  93.         return NULL;
  94.     }
  95.  
  96.  
  97.     /* Create the search pattern */
  98.     strcpy(scanname, filename);
  99.     if (strchr("/\\", *(scanname + strlen(scanname) - 1)) == NULL)
  100.         strcat(scanname, "/*.*");
  101.     else
  102.         strcat(scanname, "*.*");
  103.  
  104.  
  105.     segread(&segregs);
  106. #if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) )
  107.     segregs.ds = FP_SEG(buff);
  108.     srv.x.dx = FP_OFF(buff);
  109. #else
  110.     srv.x.dx = (unsigned int) buff;
  111. #endif
  112.     srv.h.ah = 0x1a;    /* Set DTA to DS:DX */
  113.     intdosx(&srv, &srv, &segregs);
  114.  
  115.  
  116. #if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) )
  117.     segregs.ds = FP_SEG(scanname);
  118.     srv.x.dx = FP_OFF(scanname);
  119. #else
  120.     srv.x.dx = (unsigned int) scanname;
  121. #endif
  122.     srv.x.cx = 0xff;    /* Search mode */
  123.  
  124.  
  125.     for (srv.h.ah = 0x4e; !intdosx(&srv, &srv, &segregs); srv.h.ah = 0x4f) {
  126.         if ((result = (char *) realloc(result, reslen + strlen(buff->fn) + 1)) ==
  127.  NULL) {
  128.             free(p);
  129.             free(oldresult);
  130.             return NULL;
  131.         }
  132.         oldresult = result;
  133. #ifdef CONVERT_TO_LOWER_CASE
  134.         strcpy(result + reslen, strlwr(buff->fn));
  135. #else
  136.         strcpy(result + reslen, buff->fn);
  137. #endif
  138.         reslen += strlen(buff->fn) + 1;
  139.     }
  140.  
  141.  
  142.     if (!(result = realloc(result, reslen + 1))) {
  143.         free(p);
  144.         free(oldresult);
  145.         return NULL;
  146.     } else {
  147.         p->start = result;
  148.         p->curr = result;
  149.         *(result + reslen) = '\0';
  150.         return p;
  151.     }
  152. }
  153.  
  154.  
  155.  
  156.  
  157. struct direct  *
  158. readdir(DIR *dirp)
  159. {
  160.     char           *p;
  161.     register        len;
  162.     static          dummy;
  163.  
  164.  
  165.     p = dirp->curr;
  166.     len = strlen(p);
  167.     if (*p) {
  168.         dirp->curr += len + 1;
  169.         strcpy(dirp->dirstr.d_name, p);
  170.         dirp->dirstr.d_namlen = len;
  171.         /* To fool programs */
  172.         dirp->dirstr.d_ino = ++dummy;
  173.         return &(dirp->dirstr);
  174.     } else
  175.         return NULL;
  176. }
  177.  
  178.  
  179. long
  180. telldir(DIR *dirp)
  181. {
  182.     return (long) dirp->curr;    /* ouch! pointer to long cast */
  183. }
  184.  
  185.  
  186. void
  187. seekdir(DIR *dirp, long loc)
  188. {
  189.     dirp->curr = (char *) loc;    /* ouch! long to pointer cast */
  190. }
  191.  
  192.  
  193. void
  194. rewinddir(DIR *dirp)
  195. {
  196.     dirp->curr = dirp->start;
  197. }
  198.  
  199.  
  200. void
  201. closedir(DIR *dirp)
  202. {
  203.     free(dirp->start);
  204.     free(dirp);
  205. }
  206.